import java.util.Scanner;

public class matrix {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        int T = in.nextInt();
        while(T-->0){
            int C = in.nextInt();
            int[] directs = new int[C];
            for(int i=0;i<C;i++){
                directs[i] = in.nextInt();
            }
            int M = in.nextInt();
            int N = in.nextInt();
            int[][] Marix = new int[M][N];
            for(int i=0;i<M;i++){
                for(int j=0;j<N;j++){
                    Marix[i][j] = in.nextInt();
                }
            }
            for(int d:directs){
                switch (d){
                    case 0: up(Marix); break;
                    case 1: left(Marix); break;
                    case 2: down(Marix); break;
                    case 3: right(Marix); break;
                    default: break;
                }
            }
            for(int i=0;i<M;i++){
                for(int j=0;j<N;j++){
                    System.out.print(Marix[i][j]);
                    if(j<N-1){
                        System.out.print(" ");
                    }
                }
            }
            System.out.println();
        }
    }
    private static void up(int[][] matrix){
        int rows = matrix.length;
        int cols = matrix[0].length;
        for(int i=0;i<cols;i++){
            int[] colnums = new int[rows];
            for(int j=0;j<rows;j++){
                colnums[j] = matrix[j][i];
            }
            int[] merged = process(colnums,false);
            for(int j=0;j<rows;j++){
                matrix[j][i]=merged[j];
            }
        }
    }
    private static void down(int[][] matrix){
        int rows = matrix.length;
        int cols = matrix[0].length;
        for(int i=0;i<cols;i++){
            int[] colnums = new int[rows];
            for(int j=0;j<rows;j++){
                colnums[j] = matrix[j][i];
            }
            int[] merged = process(colnums,true);
            for(int j=0;j<rows;j++){
                matrix[j][i]=merged[j];
            }
        }
    }
    private static void left(int[][] matrix){
        int rows = matrix.length;
        for(int i=0;i<rows;i++){
            matrix[i] = process(matrix[i],false);
        }
    }
    private static void right(int[][] matrix){
        int rows = matrix.length;
        for(int i=0;i<rows;i++){
            matrix[i] = process(matrix[i],true);
        }
    }
    private static int[] process(int[] line, boolean reverse){
        int len = line.length;
        if(reverse){
            invert(line);
        }
        int[] buffer = new int[len];
        int pos = 0;
        for(int val:line){
            if(val!=0){
                buffer[pos++] = val;
            }
        }
        int[] merged = new int[len];
        int index = 0;
        for(int i=0;i<pos;i++){
            if(i<pos-1 && buffer[i]==buffer[i+1]){
                merged[index++] = buffer[i] *2;
                i++;
            }else {
                merged[index++] = buffer[i];
            }
        }
        if(reverse){
            invert(merged);
        }
        return merged;
    }
    private static void invert(int[] arr){
        int left =0,right = arr.length-1;
        while(left<right){
            int temp = arr[left];
            arr[left] = arr[right];
            arr[right] = temp;
            left++;
            right--;
        }
    }
}
